package ru.spb.osll.myfit.client.widget;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import ru.spb.osll.myfit.common.*;

public class PageExecutingListenerImpl implements ExecutingListener {
  
  ArrayList<LinkedList<Integer>> indexes = new ArrayList<LinkedList<Integer>>();
  private int executedTable = 0;
  private PageWidget rootPageWidget;
//  private boolean m_finished=false;

  public PageExecutingListenerImpl(PageWidget pageWidget) {
    LinkedList<Integer> list = new LinkedList<Integer>();
    rootPageWidget = pageWidget;
    indexTables(list, rootPageWidget);
  }

//  public boolean getFinished() {
//    return m_finished;
//  }

  @Override
  public void finish() {
    executedTable = 0;
  }

  private void indexTables(List<Integer> prevIndexes, PageWidget pageWidget) {
    int size = pageWidget.getWidgetCount();

    for (int i = 0; i < size; i++) {
      PageElementWidget widget = pageWidget.getPageElementWidget(i);
      PageElementType type = widget.getType();
      switch (type) {
      case TABLE:
        LinkedList<Integer> newList = new LinkedList<Integer>(prevIndexes);
        newList.add(i);
        indexes.add(newList);
        break;
      case INCLUDE:
        LinkedList<Integer> list = new LinkedList<Integer>(prevIndexes);
        list.add(i);
        indexTables(list, ((IncludeWidget) widget).getPageWidget());
        break;
      case SET_UP:
          LinkedList<Integer> setUplist = new LinkedList<Integer>(prevIndexes);
          setUplist.add(i);
          indexTables(setUplist, ((SetUpWidget) widget).getPageWidget());
          break;
      case TEAR_DOWN:
          LinkedList<Integer> tearDownlist = new LinkedList<Integer>(prevIndexes);
          tearDownlist.add(i);
          indexTables(tearDownlist, ((SetUpWidget) widget).getPageWidget());
          break;
      default:
        break;
      }
    }
  }

  @Override
  public void processExecutingResult(ExecutingResult result) {
    List<Table> executedTables = result.getExecutedTables();
    if (executedTables != null) {
      int size = executedTables.size();
      if (size > executedTable) {
        for (int i = executedTable; i < size; i++) {
          // if ((result.getState() == PageExecutingResult.ExecutingState.FINISH) || (result.getState() == PageExecutingResult.ExecutingState.FAIL)) {m_finished = true;}
          insertTable(i, executedTables.get(i));
        }
        executedTable = size;
      }
    }
  }

  private void insertTable(int index, Table table) {
    Queue<Integer> queue = indexes.get(index);
    PageWidget pageWidget = rootPageWidget;
    while (queue.size() > 1) {
      int position = queue.poll();
      PageElementWidget includeWidget = pageWidget.getElementWidget(position);
      pageWidget = ((IncludeWidget) includeWidget).getPageWidget();
    }

    if (queue.size() == 1) {
      int position = queue.poll();
      if (table != null) {
        PageElement pageElement = pageWidget.removeWidget(position);
        if(pageElement instanceof Table){
          TableStyle style = ((Table)pageElement).getStyle(); 
          table.setStyle(style);
        }
        pageWidget.addPageElementWidget(table, position);
      }
    }
  }
}
